using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Diagnostics;


namespace BloodBot
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Shooting : Microsoft.Xna.Framework.GameComponent
    {
        //VertexPositionColor[] verts;
        //VertexBuffer vertexBuffer;
        BasicEffect effect;

        Model shootingModel;

        public BoundingSphere boundingSphere;

        public Matrix shootingTranslation { get; set; }
        public Matrix shootingRotation;
        public Matrix shootingScale { get; set; }
        public Vector3 position;
        public Vector3 direction;
        private float speed = 180f;

        public Color myColour;
        public float size;
        public bool removeMe = false;

        float shotThreshold;

        private int damage = 20;

        public Shooting(Game game, Color sColour, Vector3 Position, float size, Vector3 direction, float threshold, BasicEffect effect)
            : base(game)
        {
            this.effect = effect;
            this.myColour = sColour;
            this.position = Position;
            this.size = size;
            this.direction = direction;
            this.shotThreshold = threshold;

            // TODO: Construct any child components here
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            // TODO: Add your initialization code here

            shootingTranslation = Matrix.Identity;
            shootingRotation = Matrix.Identity;
            shootingScale = Matrix.Identity;

            shootingRotation.Forward = Vector3.Normalize(direction - position);
            shootingRotation.Right = Vector3.Normalize(Vector3.Cross(shootingRotation.Forward, Vector3.Up));
            shootingRotation.Up = Vector3.Normalize(Vector3.Cross(shootingRotation.Right, shootingRotation.Forward));

            shootingScale = Matrix.CreateScale(size);

            boundingSphere = new BoundingSphere(position, size);

            base.Initialize();
        }

        public void Load()
        {
            shootingModel = Game.Content.Load<Model>("Models\\Laser");

            //initialize vertices
            //verts = new VertexPositionColor[24];

            //UpdateModel();

            //vertexBuffer = new VertexBuffer(Game.GraphicsDevice, typeof(VertexPositionColor),
            //    verts.Length, BufferUsage.None);

            //vertexBuffer.SetData(verts);
        }

        public void UpdateModel()
        {
            ////Front Face Verticies
            //verts[0] = new VertexPositionColor(
            //new Vector3(-size, size, size), myColour);
            //verts[1] = new VertexPositionColor(
            //new Vector3(size, size, size), myColour);
            //verts[2] = new VertexPositionColor(
            //new Vector3(-size, -size, size), myColour);
            //verts[3] = new VertexPositionColor(
            //new Vector3(size, -size, size), myColour);

            ////Back Face Verticies
            //verts[4] = new VertexPositionColor(
            //new Vector3(size, size, -size), Color.Green);
            //verts[5] = new VertexPositionColor(
            //new Vector3(-size, size, -size), Color.Green);
            //verts[6] = new VertexPositionColor(
            //new Vector3(size, -size, -size), Color.Green);
            //verts[7] = new VertexPositionColor(
            //new Vector3(-size, -size, -size), Color.Green);

            ////Left Face Verticies
            //verts[8] = new VertexPositionColor(
            //new Vector3(-size, size, -size), myColour);
            //verts[9] = new VertexPositionColor(
            //new Vector3(-size, size, size), myColour);
            //verts[10] = new VertexPositionColor(
            //new Vector3(-size, -size, -size), myColour);
            //verts[11] = new VertexPositionColor(
            //new Vector3(-size, -size, size), myColour);

            ////Right Face Verticies
            //verts[12] = new VertexPositionColor(
            //new Vector3(size, size, size), myColour);
            //verts[13] = new VertexPositionColor(
            //new Vector3(size, size, -size), myColour);
            //verts[14] = new VertexPositionColor(
            //new Vector3(size, -size, size), myColour);
            //verts[15] = new VertexPositionColor(
            //new Vector3(size, -size, -size), myColour);

            ////Top Face Verticies
            //verts[16] = new VertexPositionColor(
            //new Vector3(-size, size, -size), myColour);
            //verts[17] = new VertexPositionColor(
            //new Vector3(size, size, -size), myColour);
            //verts[18] = new VertexPositionColor(
            //new Vector3(-size, size, size), myColour);
            //verts[19] = new VertexPositionColor(
            //new Vector3(size, size, size), myColour);

            ////Bottom Face Verticies
            //verts[20] = new VertexPositionColor(
            //new Vector3(-size, -size, size), myColour);
            //verts[21] = new VertexPositionColor(
            //new Vector3(size, -size, size), myColour);
            //verts[22] = new VertexPositionColor(
            //new Vector3(-size, -size, -size), myColour);
            //verts[23] = new VertexPositionColor(
            //new Vector3(size, -size, -size), myColour);
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public void Update(GameTime gameTime, Collisions collisions)
        {            
            // TODO: Add your update code here
            double lastUpdate = gameTime.ElapsedGameTime.TotalMilliseconds;
            
            // 180 units per second - get this from the gametime
            float updateAmount = speed * (float)(lastUpdate / 1000f);

            position += direction / updateAmount;

            shootingTranslation = Matrix.CreateTranslation(position);
            boundingSphere.Center = position;

            removeMe = collisions.CheckCollison(position, new Vector3(0, 0, 0), shotThreshold, null);

            if (position.Y <= -1)
            {
                removeMe = true;
            }

            base.Update(gameTime);
        }

        public void Draw(Camera camera)
        {
            // Copy any parent transforms.
            Matrix[] transforms = new Matrix[shootingModel.Bones.Count];
            shootingModel.CopyAbsoluteBoneTransformsTo(transforms);

            // Draw the model. A model can have multiple meshes, so loop.
            foreach (ModelMesh mesh in shootingModel.Meshes)
            {
                // This is where the mesh orientation is set, as well 
                // as our camera and projection.
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.World = transforms[mesh.ParentBone.Index] * shootingScale * shootingRotation * shootingTranslation;
                    effect.View = camera.view;
                    effect.Projection = camera.projection;
                }
                // Draw the mesh, using the effects set above.
                mesh.Draw();
            }

        //    Game.GraphicsDevice.SetVertexBuffer(vertexBuffer);

        //    //Updates Matricies
        //    effect.World = shootingTranslation;
        //    effect.View = camera.view;
        //    effect.Projection = camera.projection;
        //    effect.VertexColorEnabled = true;

        //    ////Draw the front face
        //    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
        //    {
        //        pass.Apply();
        //        Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>
        //        (PrimitiveType.TriangleStrip, verts, 0, 2);
        //        Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>
        //        (PrimitiveType.TriangleStrip, verts, 4, 2);
        //        Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>
        //        (PrimitiveType.TriangleStrip, verts, 8, 2);
        //        Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>
        //        (PrimitiveType.TriangleStrip, verts, 12, 2);
        //        Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>
        //        (PrimitiveType.TriangleStrip, verts, 16, 2);
        //        Game.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>
        //        (PrimitiveType.TriangleStrip, verts, 20, 2);
        //    }
        }

        public int GetDamage()
        {
            return damage;
        }
    }
}
